home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Fatted Calf
/
The Fatted Calf.iso
/
Applications
/
Developer
/
BBFig
/
Source
/
YapApp.m
< prev
next >
Wrap
Text File
|
1994-05-09
|
10KB
|
355 lines
/*
* YapApp.m
* Author: Ali Ozer
* Created: Mar 89 for 0.9
* Modified: Jul & Aug 89 for 1.0
* Modified: Aug 90 for 2.0.
* For BBFig to deo BoundingBox computation....
* Modified: Jan 92 for BBFig by Izumi Ohzawa (izumi@pinoko.berkeley.edu)
* Added Preferences: 92-05-14 Izumi Ohzawa.
*
* YapApp is the application class used in Yap. It implements the
* central functionality of coordinating the output and document
* windows, opening documents, etc...
*
* You may freely copy, distribute and reuse the code in this example.
* NeXT disclaims any warranty of any kind, expressed or implied,
* as to its fitness for any particular use.
*/
#import "YapApp.h"
#import "YapDocument.h"
#import "YapOutput.h"
#import <stdio.h>
#import <defaults/defaults.h>
#import <appkit/nextstd.h> // MIN, MAX, etc
#import <appkit/OpenPanel.h>
#import <appkit/Text.h>
#import <appkit/SavePanel.h>
#import <appkit/ScrollView.h>
#import <appkit/TextField.h>
#import <appkit/Button.h>
#import <objc/List.h>
#import <sys/param.h>
@implementation YapApp
- appDidInit:sender
{
static NXDefaultsVector BBFigDefaults = {
{"BBoxMargin", "2"},
{NULL}
};
NXRegisterDefaults([NXApp appName], BBFigDefaults);
bbmargin = atoi(NXGetDefaultValue([NXApp appName], "BBoxMargin"));
if(bbmargin < 0) bbmargin = 0;
if(bbmargin >20) bbmargin = 20;
return self;
}
- outputView
{
return outputView;
}
- outputWindow
{
return [outputView window];
}
#define DEFAULTWIDTH 612
#define DEFAULTHEIGHT 792
#define MINSIZE 72
#define MAXSIZE 3600
/*
* Here we have a handle to the output window, created in IB. We create
* the scroll and the yap output views and add them to this window.
*/
- setOutputWindow:anObject
{
NXRect initFrame = {{0.0, 0.0}, {DEFAULTWIDTH, DEFAULTHEIGHT}};
id scrollView = [ScrollView new];
outputView = [[YapOutput allocFromZone:[self zone]] initFrame:&initFrame];
[anObject setBackgroundGray:NX_WHITE];
[anObject removeFromEventMask:NX_KEYDOWNMASK|NX_KEYUPMASK];
[scrollView setBorderType:NX_NOBORDER];
[scrollView setHorizScrollerRequired:YES];
[scrollView setVertScrollerRequired:YES];
[anObject setContentView:scrollView];
[scrollView setDocView:outputView];
[anObject setDelegate:self]; // So we can get windowWillResize:toSize:
[anObject display];
[NXApp updateOutputWindowSize];
return self;
}
/*
* windowWillResize:toSize: is a delegate method that gets called
* when a window is being resized. In our case, we want to limit the user
* from growing the output window to a size that is greater than that of the
* view.
*/
- windowWillResize:sender toSize:(NXSize *)sz
{
if (sz->width > maxWindowSize.width) sz->width = maxWindowSize.width;
if (sz->height > maxWindowSize.height) sz->height = maxWindowSize.height;
return self;
}
/*
* updateOutputWindowSize should be called after the size of the output view is
* changed. It simply makes sure the window isn't too big for the view. If the
* window is indeed to big, it is resized smaller.
*/
- updateOutputWindowSize
{
NXRect frame, content;
// The next few lines allow us to get the window size for the window
// containing a ScrollView and the yap output view.
[[self outputView] getFrame:&frame];
[ScrollView getFrameSize:&maxWindowSize forContentSize:&(frame.size)
horizScroller:YES vertScroller:YES borderType:NX_NOBORDER];
// sizeWindow:: wants window size in content area; so we can use the
// maxWindowSize from above. But to compare it to the window frame,
// we first need to get the content area for the current frame.
[[self outputWindow] getFrame:&frame];
[Window getContentRect:&content forFrameRect:&frame
style:[[self outputWindow] style]];
if (content.size.width > maxWindowSize.width ||
content.size.height > maxWindowSize.height) {
[[self outputWindow]
sizeWindow:MIN(maxWindowSize.width, content.size.width)
:MIN(maxWindowSize.height, content.size.height)];
}
// Now we go from the content size to the window frame size, which is
// what we will use in windowWillResize:toSize:
content.size = maxWindowSize;
[Window getFrameRect:&frame forContentRect:&content
style:[[self outputWindow] style]];
maxWindowSize = frame.size;
return self;
}
/*
* newDocument simply creates a new Yap document and displays it.
*/
- newDocument:sender
{
[YapDocument new];
return self;
}
/*
* openDocument gets a file name from the user, creates a new document window,
* and loads the specified file into it.
*/
- openDocument:sender
{
// Allow ps, eps, and any other extension not handled by other apps.
// Note that "" should come first in the list.
static const char *const yapTypes[] = {"", "ps", "eps", NULL};
if ([[OpenPanel new] runModalForTypes:yapTypes]) {
if ([YapDocument newFromFile:[[OpenPanel new] filename]] == nil) {
NXRunAlertPanel (NULL, "Could not open file.", "OK", NULL, NULL);
}
}
return self;
}
/*
* appOpenFile:type: is invoked by Workspace when the user double-clicks
* on a file Yap is prepared to accept. By default, Yap is not prepared to open
* any files, however, it can easily be made to open files of certain type
* through the IB project inspector.
*/
- (int)appOpenFile:(const char *)path type:(const char *)type
{
if ([YapDocument newFromFile:path] == nil) return NO;
else return YES;
}
/*
* The following method indicates that Yap is ready to open multiple
* files at one time.
*/
- (BOOL)appAcceptsAnotherFile:sender
{
return YES;
}
/*
* Methods to load .nib files for the various panels.
*/
- showInfo:sender
{
if (!infoPanel) {
[self loadNibSection:"Info.nib" owner:self withNames:NO];
}
[infoPanel makeKeyAndOrderFront:sender];
return self;
}
- showHelp:sender
{
if (!helpPanel) {
[self loadNibSection:"Help.nib" owner:self withNames:NO];
}
[helpPanel makeKeyAndOrderFront:sender];
return self;
}
- showPrefs:sender
{
if (!prefsPanel) {
[self loadNibSection:"Prefs.nib" owner:self withNames:NO];
[self updatePreferencesPanel:sender];
}
[prefsPanel makeKeyAndOrderFront:sender];
return self;
}
- bbmarginSliderAction:sender
{
/* just reflect the slider value into field */
[marginBBoxField setIntValue:[sender intValue]];
return self;
}
- (int)bbMargin
{
return bbmargin;
}
/*
* updatePreferencesPanel: is used to copy the existing situation into
* the Prefences panel.
*/
- updatePreferencesPanel:sender
{
NXRect outputFrame;
[[self outputView] getFrame:&outputFrame];
[outputWidthField setFloatValue:NX_WIDTH(&outputFrame)];
[outputHeightField setFloatValue:NX_HEIGHT(&outputFrame)];
[showCacheButton setState:[[self outputView] isCacheShown]];
[clearCacheButton setState:[[self outputView] isCacheCleared]];
[showGridButton setState:[[self outputView] isMeshON]];
[computeBBoxButton setState:[[self outputView] isFigureBB]];
[marginBBoxSlider setIntValue:bbmargin];
[marginBBoxField setIntValue:bbmargin];
[outputWidthField selectText:sender];
return self;
}
/*
* okPreferencesPanel: causes the values in Preferences to be read into the
* application and applied to the various objects.
*/
- okPreferencesPanel:sender
{
char strbuf[80];
NXCoord desiredWidth, desiredHeight;
desiredWidth = [outputWidthField floatValue];
if (desiredWidth < MINSIZE || desiredWidth > MAXSIZE) {
desiredWidth = MIN(MAX(desiredWidth, MINSIZE), MAXSIZE);
[outputWidthField setFloatValue:desiredWidth];
}
desiredHeight = [outputHeightField floatValue];
if (desiredHeight < MINSIZE || desiredHeight > MAXSIZE) {
desiredHeight = MIN(MAX(desiredHeight, MINSIZE), MAXSIZE);
[outputHeightField setFloatValue:desiredHeight];
}
[[self outputView] sizeTo:desiredWidth :desiredHeight];
[self updateOutputWindowSize];
[[self outputView] setCacheShown:[showCacheButton state]];
[[self outputView] setCacheCleared:[clearCacheButton state]];
[[self outputView] setMeshON:[showGridButton state]];
[[self outputView] setFigureBB:[computeBBoxButton state]];
bbmargin = [marginBBoxSlider intValue];
[marginBBoxField setIntValue:bbmargin];
sprintf(strbuf, "%d\0", bbmargin);
NXWriteDefault ([NXApp appName], "BBoxMargin", strbuf);
[[sender window] orderOut:sender];
[outputWidthField selectText:sender];
return self;
}
/* This method code taken from Draw.app source */
- terminate:sender
/*
* Overridden to be sure all documents get an opportunity to be saved
* before exiting the program.
*/
{
int count, choice;
id window, document;
count = [windowList count]; /* windowList is in NXApp which this one is */
while (count--) {
window = [windowList objectAt:count];
document = [window delegate];
if ([window isDocEdited]) {
choice = NXRunAlertPanel("Quit", "You have unsaved documents.",
"Review Unsaved", "Quit Anyway", "Cancel");
if (choice == NX_ALERTOTHER) {
return self;
} else if (choice == NX_ALERTDEFAULT) {
count = [windowList count];
while (count--) {
window = [windowList objectAt:count];
document = [window delegate];
if ([document respondsTo:@selector(windowWillClose:action:)]) {
if ([document windowWillClose:window action:"Quit"]) {
[window close];
} else {
return self;
}
}
}
}
break;
}
}
[super terminate:sender];
return nil;
}
@end